zkSNARKs令人印象深刻,它可以在不执行计算的情况下验证结果的正确性,而且你甚至不会知道执行了什么操作,只知道它被正确执行了。但是,大多数关于zkSNARKs的解释都不清晰,因此它们仍然是一种“神奇”的东西,只有专业的人才会真正理解它们的工作原理以及为什么有效。事实是,zkSNARKs可以归结为四种简单的技术,本文旨在解释这些技术,任何能够理解RSA加密系统工作原理的人,也应该能够对当前使用的zkSNARKs有相当好的理解。
在前一节中,我们看到了如何将NP空间内的计算问题互相规约,其中有一些NP完全问题,它们只是所有其他NP问题的另一种表示方式,例如区块链中的交易验证问题,这使得我们很容易找到一个适用于NP中所有问题的通用zkSNARK。因此,如果我们想要使用zkSNARK来验证区块链中的交易,我们只需展示如何对一个NP完全问题进行验证,理论上而言这个问题更容易被解决。
这一节和下一节,我们将基于GGPR12论文来对zkSNARK进行构造,作者发现称为QSP的问题特别适合zkSNARKs。QSP由一组公开的多项式组成,目标是找到其中的线性组合,该组合是另一个给定多项式的倍数。此外,输入字符串的各个位限制了在证明中可以使用的多项式,更具体地说,限制了它们在线性组合中因子。接下来,我们来简单定义一下QSP问题
(1). 该域F上的多项式v_0,...,v_m,w_0,...,w_m的集合,(3). 一个可逆函数f:{(i, j) | 1 ≤ i ≤ n,j ∈ {0, 1}} → {1, ..., m}这里的任务大致上是通过因子乘以多项式并将它们相加,使得和(称为线性组合)是t的倍数。对于每个二进制输入字符串u,函数f限制了可以使用的多项式,或者更具体地说,限制了它们在线性组合中因子,具体地说:输入u被QSP接受(验证),当且仅当存在来自域F的元组a = (a_1,...,a_m),b = (b_1,...,b_m),使得如果k = f(i, u[i])对于某个i,则a_k,b_k = 1(u[i]是u的第i位),如果k = f(i, 1 - u[i])对于某个i,则a_k,b_k = 0,且目标多项式t整除v_a*w_b,其中v_a = v_0 + a_1*v_0 + ... + a_m*v_m,w_b = w_0 + b_1*w_1 + ... + b_m*w_m。请注意,如果2n小于m,则在选择元组a和b时仍然存在一些自由度,这意味着QSP仅对一定大小的输入有意义。在布尔公式的可满足性(SAT)中,可以将因子a_1,...,a_m,b_1,...,b_m看作是变量的赋值,或者称为NP证据(witness)。接下来我们来说明一下QSP属于NP的原因,注意验证者所需做的仅是检查多项式t是否整除v_a *w_b,这是一个可以在多项式时间内解决的问题。我们在这里不讨论从通用计算或电路到QSP的规约,因为它对于理解一般概念没有作用,你只需要知道QSP是NP完全的,任何NP空间的问题都可以在多项式时间内规约到QSP上。在实践中,规约是“工程”部分-必须以更为巧妙的方式进行,以使得结果QSP尽可能小且具有其他一些好的特性。我们已经可以看到如何更高效地验证QSP:验证任务包括检查一个多项式是否整除另一个多项式。这可以通过证明者提供另一个多项式h,使得t*h = v_a*w_b,从而将任务简化为检查多项式恒等性,或者换句话说,检查某个多项式是否为零多项式。这看起来相当容易,但是我们稍后将使用的多项式非常大(其次数大致上是原始电路中门数量的100倍),因此计算两个多项式的乘积并不容易。 因此,验证者选择一个秘密随机点s(该点是zCash的“toxic waste”之一),计算所有k的数字t(s),v_k(s)和w_k(s),并从中计算v_a(s)和w_b(s),然后仅检查t(s)*h(s) = v_a(s)*w_b(s)。因此,一组多项式相加,与标量相乘和多项式乘积的工作简化为域乘法和加法。仅在单个点上检查多项式恒等性而不是在所有点上检查,当然会降低安全性,但是如果t*h - v_a*w_b不是零多项式,证明者可以欺骗的唯一方法是她在证明之前先知道多项式中的所有零点,但是因为她在证明之前不会事先知道s,而且零的总数(多项式的次数)与s在大数中(域元素的数量)相比微不足道,这在实际应用中是非常安全的。https://blog.ethereum.org/2016/12/05/zksnarks-in-a-nutshell作者:Christian Reitwiessner分享仅供学习参考,若有不当,请联系我们处理。